﻿using ElasticSearchTest.Common;
using ElasticSearchTest.Model;
using Newtonsoft.Json;
using NPOI.HPSF;
using PMS.Search.Domain.Entities;
using PMS.Search.Elasticsearch.Model;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;

namespace CommTest
{
    public class ReadText
    {
        public static void Test()
        {
            //TestRepeatOpenFileTimes();
            //TestRepeatOpenFileHandleEqual();
            return;
            IEnumerable<GroupCount> q = GetKeywords();
            var filename = "D:\\study\\keyword-csv.csv";
            SaveCsv(q, filename);
        }

        public static IEnumerable<GroupCount> GetKeywordByHistory(bool readCache = true)
        {
            var filename = "D:\\study\\keyword-csv.csv";
            if (readCache && File.Exists(filename))
            {
                List<GroupCount> keywords = new List<GroupCount>();
                StreamReader reader = File.OpenText(filename);
                var line = reader.ReadLine();
                int i = 0;
                //while(reader.EndOfStream)
                while (line != null && line != string.Empty && i++ < 100000000)
                {
                    var model = GroupCount.Parse(line);
                    if (model != null)
                    {
                        keywords.Add(model);
                    }
                    line = reader.ReadLine();
                }
                return keywords;
            }
            else
            {
                IEnumerable<GroupCount> keywords = GetKeywords();
                SaveCsv(keywords, filename);
                return keywords;
            }
        }

        public static IEnumerable<CdnLog> GetCdnLogs()
        {
            FileStream stream = File.OpenRead("D:\\sxb\\docs\\cos\\resultdump.json");
            StreamReader reader = new StreamReader(stream);


            List<CdnLog> data = new List<CdnLog>();

            var line = reader.ReadLine();
            int i = 0;
            //while(reader.EndOfStream)
            while (line != null && line != string.Empty && i++ < 100000000)
            {
                var model = JsonConvert.DeserializeObject<CdnLog>(line);
                if (model != null)
                {
                    data.Add(model);
                }
                line = reader.ReadLine();
            }
            return data;
        }

        public static IEnumerable<GroupCount> GetKeywords()
        {
            FileStream stream = File.OpenRead("D:\\study\\history-prod.json");
            StreamReader reader = new StreamReader(stream);

            //char[] chars = new char[1000];
            //reader.Read(chars, 0, 1000);
            //var data = string.Join("",  chars);

            List<string> keywords = new List<string>();

            var line = reader.ReadLine();
            int i = 0;
            //while(reader.EndOfStream)
            while (line != null && line != string.Empty && i++ < 100000000)
            {
                var model = JsonConvert.DeserializeObject<EsBaseModel<SearchHistory>>(line);
                if (model != null && model._source != null)
                {
                    keywords.Add(model._source.SearchWord);
                }
                line = reader.ReadLine();
            }

            var q = from key in keywords
                    group key by key into g
                    orderby g.Count() descending
                    select new GroupCount
                    {
                        SearchWord = g.Key,
                        TotalCount = g.LongCount()
                    }
                    ;
            return q;
        }

        public static void TestRepeatOpenFileHandleEqual()
        {
            using
            FileStream stream = File.OpenRead("D:\\study\\history.json");
            StreamReader reader = new StreamReader(stream);
            IntPtr handle = stream.Handle;
            var safeFileHandle = stream.SafeFileHandle;
            var safeHandle = safeFileHandle.DangerousGetHandle();
            Debug.Assert(handle == safeHandle, "handle equals safe handle");

            using
            FileStream stream2 = File.OpenRead("D:\\study\\history.json");
            var safeFileHandle2 = stream2.SafeFileHandle;
            var safeHandle2 = safeFileHandle2.DangerousGetHandle();
            Debug.Assert(handle.Equals(safeHandle2), "handle not equals another open file handle");
        }

        public static void TestRepeatOpenFileTimes()
        {
            //可以大量开, 不会报错
            List<Stream> streams = new List<Stream>();
            for (int i = 0; i < 100000; i++)
            {
                FileStream stream = File.OpenRead("D:\\study\\history.json");
                streams.Add(stream);
            }

            for (int i = 0; i < 1000000; i++)
            {
                FileStream stream = File.OpenRead("D:\\study\\history.json");
            }
        }

        //StreamWriter
        public static void SaveTextCsv(IEnumerable<GroupCount> list)
        {
            using StreamWriter inputStream = File.CreateText("D:\\study\\keyword-csv.csv");
            inputStream.Write("\uFEFF");
            foreach (var item in list)
            {
                inputStream.WriteLine($"{item.SearchWord},{item.TotalCount}");
            }
            inputStream.Flush();
            inputStream.Close();
        }

        //FileStream
        public static void SaveCsv(IEnumerable<GroupCount> list, string filename)
        {
            using FileStream inputStream = File.Create(filename);
            var bom = Encoding.Default.GetBytes($"\uFEFF");
            inputStream.Write(bom);
            foreach (var item in list)
            {
                var keyBytes = Encoding.Default.GetBytes($"{item.SearchWord},{item.TotalCount}\r\n");
                inputStream.Write(keyBytes);
            }
            inputStream.Flush();
            inputStream.Close();
        }

        public static void SaveTxt(IEnumerable<string> keywords, string filename) {
            using var inputStream = File.Create(filename);
            foreach (var key in keywords)
            {
                var keyBytes = Encoding.UTF8.GetBytes(key + "\r\n");
                inputStream.Write(keyBytes);
            }
            inputStream.Flush();
            inputStream.Close();
        }
    }
}
